#include "fpga_interface.h"
#include "sense_node.h"

/**
 * @brief 启动一次检测
 *
 * @param level 门限，测试可以使用3000000
 */
void start_FFT_once(uint32_t level)
{
    // 感知门限调整
    spi_write_fpga(1, 0x30, level & 0xFFFF);
    spi_write_fpga(1, 0x31, level >> 16);

    // Detect_en
    // 采用单片机控制扫频的方式进行工作，一次使能给出检测结果，检测结果写入RAM中，单片机从Page3读取相应数据，然后启动下一次FFT检测
    spi_write_fpga(1, 0x32, 0);
    spi_write_fpga(1, 0x32, 1);
    spi_write_fpga(1, 0x32, 0);
}

/**
 * @brief 读取检测结果
 *
 * @return uint16_t* 保存FFT结果的数组
 */
uint16_t *read_FFT_RAM()
{
    static uint16_t fft_ram[FFT_RAM_SIZE];
    for (int i = 0; i < FFT_RAM_SIZE; i++)
    {
        // fft_ram[i] = spi_read_fpga(3, i);
        /****** 临时测试数据 ******/
        fft_ram[i] = i * 10;
    }
    return fft_ram;
}

/**
 * @brief Get the FFT state object

 *
 * @return uint16_t
 * 1:检测已完成
 * 0:检测未完成但RAM已满
 * 如果RAM满了仍未检测完成，则表示信号太多，可以根据最大信号值调整门限
 */
uint16_t get_FFT_state()
{
    return spi_read_fpga(1, 0x33);
}

/**
 * @brief 启动数字下变频
 *
 * @param center_frequency
 * 中心频率值，中心频率值根据输入的信号来设定，参数设置的计算方法：65536-320*f，f表示需要产生的数字本振频率
 * @param band_sel 带宽选择参数 1：5K 2：25K 3：60K 4：200K 5：1.28M 6：6.4M`
 * @param channel 通道号，模块支持同时两路数字下变频并行处理
 */
void start_DDC(uint16_t center_frequency_100kHz, uint16_t band_sel, uint16_t channel)
{
    if (channel > 3)
        channel = 0;
    uint16_t freq_code = 65536 - 32 * center_frequency_100kHz;
    spi_write_fpga(1, 0x08 + channel, freq_code);
    spi_write_fpga(1, 0x0c + channel, band_sel);
    spi_write_fpga(1, 0x10 + channel, 1);
}

/**
 * @brief 关闭数字下变频
 *
 * @param channel 通道号
 */
void stop_DDC(uint16_t channel)
{
    if (channel > 3)
        channel = 0;
    spi_write_fpga(1, 0x10 + channel, 0);
}

/**
 * @brief 保存数字下变频的结果
 * 
 * @param StoreLength_Ltime 存储时长
 * @param channel 通道号 
 */
void store_DDC_result(uint32_t StoreLength_Ltime, uint16_t channel)
{
    if (channel > 1)
        channel = 0;

    spi_write_fpga(1, 0x18, StoreLength_Ltime & 0xFFFF);
    spi_write_fpga(1, 0x19, StoreLength_Ltime >> 16);

    // RX通道1数据存储可用空间大小，单位为256bit，空间存满后，重新开始套圈
    spi_write_fpga(2, 0x09, 0x2000);
    spi_write_fpga(2, 0x0A, 0x0);

    // RX通道1数据存储，长度单位为256bit，此值为0表示不间断存储，直到sp1wr_stop有效
    spi_write_fpga(2, 0x07, 0x1000);
    spi_write_fpga(2, 0x08, 0x0);

    // 写入1开启一次RX通道1数据存储，存储过程结束后自动归0
    spi_write_fpga(2, 0x0b, 1);

    // RX通道1启动存储数据，写入1再写入0时启动一次存储，存储时长为StoreLength_Ltime1
    spi_write_fpga(1, 0x16, 1);
    spi_write_fpga(1, 0x16, 0);
}

/**
 * @brief 设置时标
 * 
 * @param min 分
 * @param sec 秒
 * @param day 日
 * @param hour 小时
 */
void set_timestamp(uint8_t min, uint8_t sec, uint8_t day, uint8_t hour)
{
    spi_write_fpga(1, 0x14, min << 8 | sec);
    spi_write_fpga(1, 0x15, day << 8 | hour);
}
